package org.fluidripple.socket.session;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

@Slf4j
public class SessionManager {

    private static final AttributeKey<Object> SESSION_KEY = AttributeKey.valueOf("session");


    //会话存储
    private static SessionStore sessionStore=new SessionStore();

    /**
     * 获取session对象，设备建立链接阶段
     * @param context
     * @return
     */
    public static Session getSession(ChannelHandlerContext context){
        Channel channel = context.channel();
        Session session = getSession(channel);
        if (session == null) {
            session = newSession(channel);
            setSession(channel, session);
        }
        return session;
    }
    /**
     * 获取session对象，设备建立链接阶段
     * @param channel
     * @return
     */
    private static Session newSession(Channel channel) {
        InetSocketAddress inet = (InetSocketAddress) channel.remoteAddress();
        String ip = inet.getHostString();
        Session sessionIp = sessionStore.getSessionIp(ip);
        if (Objects.nonNull(sessionIp)) {
            //找到重复的ip了，说明当前设备已经在建立连接
            channel.close();
            return sessionIp;
        }
        Session session = new Session(channel, inet);
        return session;
    }

    /**
     * 获取会话
     */
    public static Session getSession(String deviceNo){
        Session session = sessionStore.getSession(deviceNo);
        if (Objects.isNull(session)) {
            throw new RuntimeException("当前设备已经断开连接");
        }
        return session;
    }

    public static void setSession(Channel channel, Session session){
        channel.attr(SESSION_KEY).set(session);
    }

    public static Session getSession(Channel channel){
        return (Session) channel.attr(SESSION_KEY).get();
    }

    /**
     * 设备注册/登录阶段
     */
    public static void register(Session session){

        sessionStore.storeSession(session.getDeviceSerializable(),session);
    }

    /**
     * 设备断开链接阶段
     * @param session
     */
    public static void inactive(Session session) {
        log.info("\uD83C\uDF3A 删除{} 设备的session",session.getDeviceSerializable());
        sessionStore.removeSession(session);
    }

    /**
     * 获取所有的session
     */
    public static Collection<Session> list(){
        return sessionStore.list();
    }

    public static Session getSessionById(String sessionId) {
        Collection<Session> list = list();
        Optional<Session> any = list.stream().filter(v -> v.getSessionId().equals(sessionId)).findAny();
        if (!any.isPresent()) {
            throw new RuntimeException("当前设备已经断开连接");
        }
        return any.get();
    }
}
